#include "raft/node.h"
#include "raft/options.h"
#include "raft/raft.h"

int main() {
  std::vector<std::shared_ptr<libraft::Raft>> rafts;

  libraft::Options options1(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8901, "data1", "meta1", "log1");
  libraft::RaftNode raft_node1(options1);
  std::shared_ptr<libraft::Raft> raft1 = raft_node1.StartNode("raft1_example1/");
  rafts.push_back(raft1);

  libraft::Options options2(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8902, "data2", "meta2", "log2");
  libraft::RaftNode raft_node2(options2);
  std::shared_ptr<libraft::Raft> raft2 = raft_node2.StartNode("raft1_example1/");
  rafts.push_back(raft2);

  libraft::Options options3(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8903, "data3", "meta3", "log3");
  libraft::RaftNode raft_node3(options3);
  std::shared_ptr<libraft::Raft> raft3 = raft_node3.StartNode("raft1_example1/");
  rafts.push_back(raft3);

  libraft::Options options4(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8904, "data4", "meta4", "log4");
  libraft::RaftNode raft_node4(options4);
  std::shared_ptr<libraft::Raft> raft4 = raft_node4.StartNode("raft1_example1/");
  rafts.push_back(raft4);

  libraft::Options options5(
      "127.0.0.1:8901,127.0.0.1:8902,127.0.0.1:8903,127.0.0.1:8904,127.0.0.1:"
      "8905",
      "127.0.0.1", 8905, "data5", "meta5", "log5");
  libraft::RaftNode raft_node5(options5);
  std::shared_ptr<libraft::Raft> raft5 = raft_node5.StartNode("raft1_example1/");
  rafts.push_back(raft5);
  LOG_INFO << "raft1 electing leader...........";

  std::shared_ptr<libraft::Raft> leader_raft = nullptr;
  while (1) {
    for (auto &iter : rafts) {
      if (iter->IsLeader()) {
        leader_raft = iter;
        goto label;
      }
    }
	
    std::string server_status;
    raft1->GetServerStatus(&server_status);
    LOG_INFO << server_status;

    raft2->GetServerStatus(&server_status);
    LOG_INFO << server_status;

    raft3->GetServerStatus(&server_status);
    LOG_INFO << server_status;

    raft4->GetServerStatus(&server_status);
    LOG_INFO << server_status;

    raft5->GetServerStatus(&server_status);
    LOG_INFO << server_status;

    LOG_INFO << "raft1 electing leader... sleep 2s";
    std::this_thread::sleep_for(std::chrono::seconds(2));
  }

label:
  while (1) {
    int count = 0;
    for (int i = 0; i < 2000; i++) {
      std::string key = std::to_string(count++);
      assert(leader_raft->Write(key, "").ok());
      std::string value;
      assert(leader_raft->Read(key, &value).ok());
    }

    std::string server_status;
    leader_raft->GetServerStatus(&server_status);
    LOG_INFO << server_status;
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
}
